﻿using Castle.Core.Logging;
using System.Transactions;
using Yto.Common.Dependency;

namespace Yto.Unitwork
{
    public class UnitManager : IUnitManager, ITransient
    {
        private readonly ICtnResolver ctnResolver;
        private ICurrentUnit currentUnit;

        public ILogger Logger { get; set; }

        public UnitManager(ICtnResolver ctnResolver, ICurrentUnit currentUnit)
        {
            this.ctnResolver = ctnResolver;
            this.currentUnit = currentUnit;
            Logger = NullLogger.Instance;
        }
        public ICompleteHandle Begin()
        {
            return Begin(new UnitworkOptions() { IsTransactional = true,TrsctScpOpt = TransactionScopeOption.Required });
        }

        public ICompleteHandle Begin(UnitworkOptions options)
        {
            var outerUow = currentUnit.Current;
            if(options.TrsctScpOpt == TransactionScopeOption.Required && outerUow != null)
            {
                return new InnerCompleteHandle();
            }

            var unitwork = ctnResolver.Resolver<IUnitwork>();

            unitwork.Completed += (sender, args) =>
            {
                currentUnit.Current = null;
            };
            unitwork.Failed += (sender, args) =>
            {
                if (args.Exception != null)
                {
                    Logger.Error(args.Exception.Message, args.Exception);
                }
                currentUnit.Current = null;
            };
            unitwork.Disposed += (sender, args) =>
            {
                ctnResolver.Realse(unitwork);
            };
            unitwork.Begin(options);

            currentUnit.Current = unitwork;
            return unitwork;
        }
    }
}
